import numpy as np
import torch


# 一、直接创建张量
# -------- example 1 --------
# 通过 torch.tensor 创建张量
#
# flag = True
flag = False
if flag:
    arr = np.ones((3, 3))
    print("ndarray的数据类型：", arr.dtype)

    t = torch.tensor(arr, device="cuda")  # 放在gpu上
    # t = torch.tensor(arr)  # 张量数据放在cpu上
    print(t)

#  -------- example 2 ----------
# 通过 torch.from_numpy 创建张量
# flag = True
flag = False
if flag:
    arr = np.array([[1, 2, 3], [4, 5, 6]])
    t = torch.from_numpy(arr)
    print("numpy array: ", arr)
    print("tensor: ", t)

    # 验证用torch.from_numpy创建张量时，张量与原数据(arr)共享内存
    print("\n修改arr")
    arr[0, 0] = 0
    print("numpy array: ", arr)
    print("tensor: ", t)

    print("\n修改tensor")
    t[0, 1] = -10
    print("numpy array: ", arr)
    print("tensor: ", t)

# 二、通过数值创建张量
# -------- example 3 --------
# 通过 torch.zeros 创建张量
# flag = True
flag = False
if flag:
    out_t = torch.tensor([1])
    print("out_t: ", out_t)

    # size: 张量的形状;
    # out: 输出的张量
    t = torch.zeros((3, 3), out=out_t)  # 将输出的张量返回给t，同时也报存在out_t中

    print(t, '\n', out_t)  # t和out_t一样
    print(id(t), id(out_t), id(t) == id(out_t))


# --------- example 4 ---------
# 通过 torch.full 创建张量
# flag = True
flag = False
if flag:
    # size: 张量形状
    # full_value：填充值
    t = torch.full((3, 3), 10)
    print(t)

# 通过 touch.arange创建等差数列张量
# flag = True
flag = False
if flag:
    # (start, end, step,...)
    # step是步长
    t = torch.arange(2, 10, 2)  # 区间[start, end)
    print(t)

# 通过torch.linspace()创建均分的1维张量
# flag = True
flag = False
if flag:
    # [start, end]
    # steps是总共有多少个元素
    t = torch.linspace(2, 10, 10)
    print(t)

# 三、通过概率分布创建张量
# 通过torch.normal创建正态分布张量
flag = True
# flag = False
if flag:
    """
    # mean: 张量  std: 张量
    mean = torch.arange(1, 5, dtype=torch.float)
    std = torch.arange(1, 5, dtype=torch.float)

    # 都是张量，一一对应
    # 通过采样每一个正态分布得到,一个均值和方差采一个样本值
    t_normal = torch.normal(mean, std)
    print("mean:{}\nstd:{}".format(mean, std))
    print(t_normal)
    """

    """
    # mean: 标量 std：标量
    t_normal = torch.normal(0., 1., size=(4, 4))  # 高斯分布
    print(t_normal)
    """

    # mean: 张量 std：标量
    mean = torch.arange(1, 5, dtype=torch.float)
    std = 1
    t_normal = torch.normal(mean, std)  # 每一个均值对应分布的标准差都是1
    print("mean:{}\nstd:{}".format(mean, std))
    print(t_normal)
